package org.cainiao.portal.dto.response.document;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import org.cainiao.api.lark.dto.response.docs.docs.apireference.document.text.LarkLink;
import org.cainiao.api.lark.dto.response.docs.docs.apireference.document.text.LarkTextElement;
import org.cainiao.api.lark.dto.response.docs.docs.apireference.document.text.LarkTextElementStyle;
import org.cainiao.api.lark.dto.response.docs.docs.apireference.document.text.LarkTextRun;
import org.springframework.lang.NonNull;

import java.io.Serial;
import java.io.Serializable;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * <br />
 * <p>
 * Author: Cai Niao(wdhlzd@163.com)<br />
 */
@Builder
@Data
public class CnElement implements Serializable, Cloneable {

    @Serial
    private static final long serialVersionUID = 7627999754366938713L;

    private static final byte STYLE_OFFSET_ITALIC = 1;
    private static final byte STYLE_OFFSET_STRIKETHROUGH = STYLE_OFFSET_ITALIC + 1;
    private static final byte STYLE_OFFSET_UNDERLINE = STYLE_OFFSET_STRIKETHROUGH + 1;
    private static final byte STYLE_OFFSET_INLINE_CODE = STYLE_OFFSET_UNDERLINE + 1;
    private static final byte STYLE_OFFSET_BACKGROUND_COLOR = STYLE_OFFSET_INLINE_CODE + 1;
    private static final byte STYLE_OFFSET_TEXT_COLOR = STYLE_OFFSET_BACKGROUND_COLOR + 5;

    /**
     * 掩码：加粗
     */
    public static final int STYLE_MASK_BOLD = 1;
    /**
     * 掩码：斜体
     */
    public static final int STYLE_MASK_ITALIC = 1 << STYLE_OFFSET_ITALIC;
    /**
     * 掩码：删除线
     */
    public static final int STYLE_MASK_STRIKETHROUGH = 1 << STYLE_OFFSET_STRIKETHROUGH;
    /**
     * 掩码：下划线
     */
    public static final int STYLE_MASK_UNDERLINE = 1 << STYLE_OFFSET_UNDERLINE;
    /**
     * 掩码：inline 代码
     */
    public static final int STYLE_MASK_INLINE_CODE = 1 << STYLE_OFFSET_INLINE_CODE;


    /**
     * 文本内容
     */
    private String content;

    /**
     * 超链接的 URL
     */
    private String url;

    /**
     * 用不同的位表示不同的信息，4 字节，32 位，1 表示 true，0 表示 false<br />
     * <ol>
     *     <li>第 1 位：加粗</li>
     *     <li>第 2 位：斜体</li>
     *     <li>第 3 位：删除线</li>
     *     <li>第 4 位：underline，下划线</li>
     *     <li>第 5 位：inline_code，inline 代码</li>
     *     <li>第 6 ~ 10 位：background_color，背景色</li>
     *     <li>第 11 ~ 15 位：text_color，字体颜色</li>
     * </ol>
     */
    private int style;

    /**
     * 评论 ID 列表
     */
    @Schema(description = "评论 ID 列表", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private List<String> commentIds;

    public static CnElement fromLarkTextElement(@NonNull LarkTextElement larkTextElement) {
        LarkTextRun larkTextRun = larkTextElement.getTextRun();
        CnElement cnElement = CnElement.builder().content(larkTextRun == null ? null : larkTextRun.getContent()).build();
        LarkTextElementStyle larkTextElementStyle = larkTextRun == null ? null : larkTextRun.getTextElementStyle();
        LarkLink larkLink = larkTextElementStyle == null ? null : larkTextElementStyle.getLink();
        if (larkLink != null) {
            cnElement.setUrl(URLDecoder.decode(larkLink.getUrl(), StandardCharsets.UTF_8));
        }
        int style_ = 0;
        if (larkTextElementStyle != null) {
            if (larkTextElementStyle.isBold()) {
                style_ |= STYLE_MASK_BOLD;
            }
            if (larkTextElementStyle.isItalic()) {
                style_ |= STYLE_MASK_ITALIC;
            }
            if (larkTextElementStyle.isStrikethrough()) {
                style_ |= STYLE_MASK_STRIKETHROUGH;
            }
            if (larkTextElementStyle.isUnderline()) {
                style_ |= STYLE_MASK_UNDERLINE;
            }
            if (larkTextElementStyle.isInlineCode()) {
                style_ |= STYLE_MASK_INLINE_CODE;
            }
        }
        Integer backgroundColor = larkTextElementStyle == null ? null : larkTextElementStyle.getBackgroundColor();
        if (backgroundColor != null) {
            style_ |= backgroundColor << STYLE_OFFSET_BACKGROUND_COLOR;
        }
        Integer textColor = larkTextElementStyle == null ? null : larkTextElementStyle.getTextColor();
        if (textColor != null) {
            style_ |= textColor << STYLE_OFFSET_TEXT_COLOR;
        }
        cnElement.setStyle(style_);
        return cnElement;
    }

    @Override
    public CnElement clone() {
        try {
            return (CnElement) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }
    }
}
